package com.lcq.gulimall.product.service.impl;

import com.alibaba.fastjson.TypeReference;
import com.lcq.common.to.OrderSpuInfoTo;
import com.lcq.common.utils.R;
import com.lcq.gulimall.product.entity.*;
import com.lcq.gulimall.product.feign.SeckillFeignService;
import com.lcq.gulimall.product.feign.WareFeignService;
import com.lcq.gulimall.product.service.*;
import com.lcq.gulimall.product.vo.AttrGroupVo;
import com.lcq.gulimall.product.vo.SeckillInfoVo;
import com.lcq.gulimall.product.vo.SkuItemVo;
import com.mysql.cj.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lcq.common.utils.PageUtils;
import com.lcq.common.utils.Query;

import com.lcq.gulimall.product.dao.SkuInfoDao;


@Service("skuInfoService")
public class SkuInfoServiceImpl extends ServiceImpl<SkuInfoDao, SkuInfoEntity> implements SkuInfoService {
    @Autowired
    SpuInfoDescService spuInfoDescService;

    @Autowired
    WareFeignService wareFeignService;

    @Autowired
    SkuImagesService skuImagesService;

    @Autowired
    SeckillFeignService seckillFeignService;

    @Autowired
    AttrGroupService attrGroupService;

    @Autowired
    SkuSaleAttrValueService skuSaleAttrValueService;

    @Autowired
    SpuInfoService spuInfoService;

    @Autowired
    ThreadPoolExecutor executor;
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        /**
         * key: mate
         * catelogId: 225
         * brandId: 8
         * min: 1000
         * max: 6000
         * */

        QueryWrapper<SkuInfoEntity> query = new QueryWrapper<>();
        String catelogId = (String) params.get("catelogId");
        if(!StringUtils.isNullOrEmpty(catelogId)&&Long.valueOf(catelogId)!=0){

            query.and((q)->{
                q.eq("catalog_id",catelogId);
            });
        }

        String brandId = (String) params.get("brandId");
        if(!StringUtils.isNullOrEmpty(brandId)&&Long.valueOf(brandId)!=0){
            query.and((q)->{
                q.eq("brand_id",brandId);
            });
        }

        String min = (String) params.get("min");
        if(!StringUtils.isNullOrEmpty(min)&&Long.valueOf(min)!=0){
            query.and((q)->{
                q.ge("price",min);
            });
        }

        String max = (String) params.get("max");
        if(!StringUtils.isNullOrEmpty(max)&&Long.valueOf(max)!=0){
            query.and((q)->{
                q.le("price",max);
            });
        }

        String key = (String) params.get("key");
        if(!StringUtils.isNullOrEmpty(key)){
            query.and((q)->{
                q.like("sku_name",key).or().like("sku_title",key).or().like("sku_subtitle",key);
            });
        }

        IPage<SkuInfoEntity> page = this.page(
                new Query<SkuInfoEntity>().getPage(params),
                query
        );

        return new PageUtils(page);
    }

    @Override
    public SkuItemVo getSkuItem(Long skuId) throws ExecutionException, InterruptedException {
        SkuItemVo skuItemVo = new SkuItemVo();

        CompletableFuture<SkuInfoEntity> skuInfoFuture = CompletableFuture.supplyAsync(() -> {
            SkuInfoEntity infoEntity = this.getById(skuId);
            if (infoEntity == null) {
                return null;
            }
            skuItemVo.setInfo(infoEntity);
            return infoEntity;
        },executor);

        CompletableFuture<Void> spuInfoFuture = skuInfoFuture.thenAcceptAsync((infoEntity) -> {
            if (infoEntity != null) {
                skuItemVo.setSpuInfo(spuInfoService.getById(infoEntity.getSpuId()));
            }
        }, executor);

        CompletableFuture<Void> descFuture = skuInfoFuture.thenAcceptAsync((infoEntity) -> {
            if (infoEntity != null) {
                skuItemVo.setDesc(spuInfoDescService.getById(infoEntity.getSpuId()));
            }
        }, executor);

        CompletableFuture<Void> groupAttrsFuture = skuInfoFuture.thenAcceptAsync((infoEntity) -> {
            if (infoEntity != null) {
                skuItemVo.setGroupAttrs(attrGroupService.getGroupAttrs(infoEntity.getCatalogId(), infoEntity.getSpuId()));
            }
        }, executor);

        CompletableFuture<Void> saleAttrFuture = skuInfoFuture.thenAcceptAsync((infoEntity) -> {
            if (infoEntity != null) {
                skuItemVo.setSaleAttr(skuSaleAttrValueService.getSaleAttr(infoEntity.getSpuId()));
            }
        }, executor);

        CompletableFuture<Void> hasStockFuture = CompletableFuture.runAsync(() -> {
            skuItemVo.setHasStock((Boolean) wareFeignService.hasStock(skuId).get("hasStock"));
        }, executor);

        CompletableFuture<Void> imagesFuture = CompletableFuture.runAsync(() -> {
            skuItemVo.setImages(skuImagesService.getBaseMapper().selectList(new QueryWrapper<SkuImagesEntity>().eq("sku_id", skuId)));
        }, executor);



        // 6.查询当前sku是否参与秒杀优惠
        CompletableFuture<Void> secKillFuture = CompletableFuture.runAsync(() -> {
            R skuSeckillInfo = seckillFeignService.getSkuSeckillInfo(skuId);
            if (skuSeckillInfo.getCode() == 0) {
                SeckillInfoVo seckillInfoVo = skuSeckillInfo.getData(new TypeReference<SeckillInfoVo>() {});
                skuItemVo.setSeckillInfoVo(seckillInfoVo);
            }
        }, executor);
        
        CompletableFuture.allOf(spuInfoFuture,descFuture,groupAttrsFuture,saleAttrFuture,hasStockFuture,imagesFuture,secKillFuture).get();
        return skuItemVo;
    }

    @Override
    public OrderSpuInfoTo getSpuInfo(Long skuId) {
        return this.getBaseMapper().getSpuInfo(skuId);
    }

}